﻿using System;
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using Xenta.Enums;
using Xenta.Operations;
using Xenta.Plugins;
using Xenta.Structs;
using Xenta.Utils;

namespace Xenta.Tests.Operations
{
    [TestFixture]
    public class MessageTests : OperationTest
    {
        protected override IEnumerable<Type> ModelMappings
        {
            get
            {
                return NHMappings.ALL;
            }
        }

        protected override IDictionary<DependencyInfo, IDependency> Dependencies
        {
            get
            {
                var components = new Dictionary<DependencyInfo, IDependency>();
                var messageSender = new Mock<IMessageSender>();
                components.Add(new DependencyInfo
                {
                    ID = "52fa95dc-61b3-47b8-af7d-9453d8269d30"
                }, messageSender.Object);
                return components;
            }
        }

        [TestCase("from", "to", "bcc", "reply", "subject", "text")]
        public void Can_CRUD(string from, string to, string bccTo, string replyTo, string subject, string text)
        {
            var message = Processor.Execute(new CreateMessage
            {
                SenderID = Guid.Parse("52fa95dc-61b3-47b8-af7d-9453d8269d30"),
                From = from,
                To = to,
                BccTo = bccTo,
                ReplyTo = replyTo,
                Subject = subject,
                Text = text
            }).Result;

            Assert.NotNull(message);
            message.From.AreEqualIgnoringCase(from);
            message.To.AreEqualIgnoringCase(to);
            message.BccTo.AreEqualIgnoringCase(bccTo);
            message.ReplyTo.AreEqualIgnoringCase(replyTo);
            message.Subject.AreEqualIgnoringCase(subject);
            message.Text.AreEqualIgnoringCase(text);
            message.Flags.AreEqual(MessageFlags.None);
            message.AreEqual(Processor.Execute(new GetMessage
            {
                EntityID = message.EntityID
            }).Result);

            from = from.Reverse();
            to = to.Reverse();
            bccTo = bccTo.Reverse();
            replyTo = replyTo.Reverse();
            subject = subject.Reverse();
            text = text.Reverse();
            var upd_message = Processor.Execute(new UpdateMessage
            {
                EntityID = message.EntityID,
                From = from,
                To = to,
                BccTo = bccTo,
                ReplyTo = replyTo,
                Subject = subject,
                Text = text,
                Flags = MessageFlags.Active
            }).Result;

            Assert.NotNull(upd_message);
            upd_message.AreEqual(message);
            upd_message.From.AreEqualIgnoringCase(from);
            upd_message.To.AreEqualIgnoringCase(to);
            upd_message.BccTo.AreEqualIgnoringCase(bccTo);
            upd_message.ReplyTo.AreEqualIgnoringCase(replyTo);
            upd_message.Subject.AreEqualIgnoringCase(subject);
            upd_message.Text.AreEqualIgnoringCase(text);
            upd_message.Flags.AreEqual(MessageFlags.Active);

            Processor.Execute(new DeleteMessage
            {
                EntityID = message.EntityID
            });
        }

        [TestCase("from", "")]
        [TestCase("", "to")]
        public void Cannot_Create_If_FromOrTo_Empty(string from, string to)
        {
            Assert.Throws<ApplicationException>(() => Processor.Execute(new CreateMessage
            {
                From = from,
                To = to
            }));
        }

        [TestCase("from", "")]
        [TestCase("", "to")]
        public void Cannot_Update_If_FromOrTo_Empty(string from, string to)
        {
            Assert.Throws<ApplicationException>(() => Processor.Execute(new UpdateMessage
            {
                From = from,
                To = to
            }));
        }
    }
}
